package cqrtplm.service.impl;

import com.ty.basic.entity.org.UserDO;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.dto.RTCertFiledFormDTO;
import cqrtplm.entity.RtCertFiledCustomerDO;
import cqrtplm.entity.RtCertFiledRatoModelsDO;
import cqrtplm.mapper.RtCertFiledRatoModelsMapper;
import cqrtplm.service.RtCertFiledRatoModelsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 机型认证清单服务实现
 */
@Service
@Slf4j
public class RtCertFiledRatoModelsServiceImpl implements RtCertFiledRatoModelsService {

    @Resource
    private RtCertFiledRatoModelsMapper rtCertFiledRatoModelsMapper;

    @Resource
    private RTLogDifferenceServiceImpl rtLogDifferenceService;

    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;

    @Override
    public RtCertFiledRatoModelsDO selectRtCertFiledRatoModelsById(String id) {
        return rtCertFiledRatoModelsMapper.selectRtCertFiledRatoModelsById(id);
    }

    @Override
    public List<RtCertFiledRatoModelsDO> selectRtCertFiledRatoModelsList(RtCertFiledRatoModelsDO rtCertFiledRatoModels) {
        return rtCertFiledRatoModelsMapper.selectRtCertFiledRatoModelsList(rtCertFiledRatoModels);
    }

    @Override
    public int insertRtCertFiledRatoModels(RtCertFiledRatoModelsDO rtCertFiledRatoModels) {
        String devCode = rtCertFiledRatoModels.getDevCode();
        String filedId = rtCertFiledRatoModels.getFiledId();
        RtCertFiledRatoModelsDO q = new RtCertFiledRatoModelsDO();
        q.setDevCode(devCode);
        q.setFiledId(filedId);

        List<RtCertFiledRatoModelsDO> old = rtCertFiledRatoModelsMapper.selectRtCertFiledRatoModelsByDevCode(q);
        if(old != null && !old.isEmpty()) {
            throw RTErrorCodeEnum.DATA_EXISTS.getException("该开发令已存在，请勿重复添加");
        } else {
            UserDO user = TyAccountContext.getUser();
            if (user == null) {
                throw new RuntimeException("用户未登录");
            }

            String snowId = String.valueOf(snowflakeIdComponent.getInstance().nextId());
            Timestamp timestamp = new Timestamp(new Date().getTime());

            rtCertFiledRatoModels.setId(snowId);
            rtCertFiledRatoModels.setCreateTime(timestamp);
            rtCertFiledRatoModels.setCreateUserId(String.valueOf(user.getOid()));
            rtCertFiledRatoModels.setCreateUserName(user.getName());

            log.info("机型认证清单-新增{},{},{},{}",
                     rtCertFiledRatoModels.getDevCode(),
                     snowId,
                     timestamp,
                     user.getName());

            return rtCertFiledRatoModelsMapper.insertRtCertFiledRatoModels(rtCertFiledRatoModels);
        }
    }

    @Override
    public int updateRtCertFiledRatoModels(RtCertFiledRatoModelsDO rtCertFiledRatoModels) {
        RtCertFiledRatoModelsDO old = rtCertFiledRatoModelsMapper.selectRtCertFiledRatoModelsById(rtCertFiledRatoModels.getId());
        if(old == null) {
            throw RTErrorCodeEnum.DATA_NOT_EXISTS.getException("该机型认证清单不存在，请检查");
        } else {
            UserDO user = TyAccountContext.getUser();
            if (user == null) {
                throw new RuntimeException("用户未登录");
            }

            Timestamp timestamp = new Timestamp(new Date().getTime());
            rtCertFiledRatoModels.setUpdateTime(timestamp);
            rtCertFiledRatoModels.setUpdateUserId(String.valueOf(user.getOid()));
            rtCertFiledRatoModels.setUpdateUserName(user.getName());

            int r = rtCertFiledRatoModelsMapper.updateRtCertFiledRatoModels(rtCertFiledRatoModels);
            if(r > 0) {
                // 记录差异日志
                rtLogDifferenceService.newLog(
                        rtCertFiledRatoModels, old,
                        rtCertFiledRatoModels.getId(),
                        rtCertFiledRatoModels.getCreateUserName(),
                        "机型认证清单",
                        "修改",
                        ""
                );
            }
            return r;
        }
    }

    @Override
    public void updateEntityList(RTCertFiledFormDTO formDTO, List<RtCertFiledRatoModelsDO> list) {
        // 获取数据库中现有的客户列表
        String filedId = formDTO.getRtCertFiledDO().getId();
        if(!list.isEmpty()){
            RtCertFiledRatoModelsDO q = new RtCertFiledRatoModelsDO();
            q.setFiledId(filedId);
            List<RtCertFiledRatoModelsDO> existingList = selectRtCertFiledRatoModelsList(q);

            // 获取数据库中所有存在的ID集合
            Set<String> existingDevCodes = existingList.stream()
                    .map(RtCertFiledRatoModelsDO::getDevCode)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            // 编辑操作进行增量处理

            // 1. 找出需要删除的记录（存在于数据库但不在新列表中）
            List<RtCertFiledRatoModelsDO> toDelete = existingList.stream()
                    .filter(existing -> list.stream().noneMatch(newItem -> Objects.equals(newItem.getDevCode(), existing.getDevCode())))
                    .collect(Collectors.toList());

            // 2. 找出需要更新的记录（devcode匹配但内容不同）
            List<RtCertFiledRatoModelsDO> toUpdate = list.stream()
                    .filter(item -> item.getDevCode() != null && existingDevCodes.contains(item.getDevCode().toString()))
                    .collect(Collectors.toList());

            // 3. 找出需要新增的记录（ID为null或不在数据库中）
            List<RtCertFiledRatoModelsDO> toInsert = list.stream()
                    .filter(item -> item.getDevCode() == null || !existingDevCodes.contains(item.getDevCode().toString()))
                    .collect(Collectors.toList());


            // 执行操作
            if (Boolean.FALSE.equals(formDTO.getEditWithoutDelete())) {
                toDelete.forEach(item -> deleteRtCertFiledRatoModelsById(item.getId()));
            }
            toUpdate.forEach(item -> {
                item.setFiledId(filedId);
                updateRtCertFiledRatoModels(item);
            });
            toInsert.forEach(item -> {
                item.setFiledId(filedId);
                insertRtCertFiledRatoModels(item);
            });
        }
    }

    @Override
    public int deleteRtCertFiledRatoModelsByIds(List<String> ids) {
        return rtCertFiledRatoModelsMapper.deleteRtCertFiledRatoModelsByIds(ids);
    }

    @Override
    public int deleteRtCertFiledRatoModelsById(String id) {
        return rtCertFiledRatoModelsMapper.deleteRtCertFiledRatoModelsById(id);
    }

    @Override
    public int deleteRtCertFiledRatoModelsByFiledId(String id) {
        return rtCertFiledRatoModelsMapper.deleteRtCertFiledRatoModelsByFiledId(id);
    }

    @Override
    public RtCertFiledRatoModelsDO selectRtCertFiledRatoModelsByDevCode(String filedId, String devCode) {
        RtCertFiledRatoModelsDO q = new RtCertFiledRatoModelsDO();
        q.setDevCode(devCode);
        q.setFiledId(filedId);
        List<RtCertFiledRatoModelsDO> result = rtCertFiledRatoModelsMapper.selectRtCertFiledRatoModelsByDevCode(q);
        if(result != null && !result.isEmpty()) {
            return result.get(0);
        }
        return null;
    }
}